package cn.roadtrip.mtravelbusinessmodule.bs.page;

import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONArray;
import cn.roadtrip.mtravelbusinessmodule.bs.comment.CommentImpl;
import cn.roadtrip.mtravelbusinessmodule.bs.shopproduct.UserTicketImpl;
import cn.roadtrip.mtravelbusinessmodule.bs.travelline.TravelLineImpl;
import cn.roadtrip.mtravelbusinessmodule.bs.tuorgroup.TourTravelImpl;
import cn.roadtrip.mtravelbusinessmodule.bs.vpo.BSTravelPageWrapper_TravelGroupVPO;
import cn.roadtrip.mtravelbusinessmodule.sql.couple.travelline.Tables;
import cn.roadtrip.mtravelbusinessmodule.sql.couple.travelline.dto.BsTravelLinePlatPreTravelLineDTO;
import cn.roadtrip.uredismodule.util.RedisUtil;
import cn.roadtrip.utilmodule.util.DataBean;
import cn.roadtrip.utilmodule.util.enumpck.Enum_MainTourTravelLineStats;
import cn.roadtrip.utilmodule.util.enumpck.Enum_TourTravelGroupType;
import cn.roadtrip.utilmodule.util.enumpck.Enum_TravelGroupTourOrderStats;
import com.google.gson.Gson;
import jakarta.annotation.PreDestroy;
import lombok.*;
import lombok.extern.slf4j.Slf4j;
import org.jooq.DSLContext;
import org.jooq.impl.DSL;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

import static cn.roadtrip.mtravelbusinessmodule.sql.couple.tables.SysCategory.SYS_CATEGORY;
import static cn.roadtrip.mtravelbusinessmodule.sql.couple.travelgroup.Tables.*;
import static cn.roadtrip.mtravelbusinessmodule.sql.couple.travelline.Tables.BS_TRAVELLINE_PLATPRETRAVELLINE;
import static cn.roadtrip.mtravelbusinessmodule.sql.couple.travelline.Tables.BS_TRAVELLINE_PRETRAVELLINESCENICGROUP;
import static cn.roadtrip.mtravelbusinessmodule.sql.couple.travelline.tables.BsScenic.BS_SCENIC;
import static cn.roadtrip.utilmodule.util.DataBean.err;
import static cn.roadtrip.utilmodule.util.DataBean.suc;

/**
 * 旅游页面封装
 */
@Component
@Slf4j
public class TravelPageWrapper {
    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private TravelLineImpl travelLineImpl;

    @Autowired
    private TourTravelImpl tourTravelImpl;

    @Autowired
    private UserTicketImpl userTicketImpl;

    @Autowired
    private DSLContext dslContext;
    private ExecutorService executor = Executors.newFixedThreadPool(4);//批量执行线程

    @PreDestroy
    public void _destroy() {
        try {
            executor.shutdown();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Data
    @Builder
    @AllArgsConstructor
    @NoArgsConstructor
    @EqualsAndHashCode
    public static class Model_getCityList {
        private String parentId;
    }

    @Data
    @Builder
    @AllArgsConstructor
    @NoArgsConstructor
    @EqualsAndHashCode
    public static class _CityModel_ {
        private String id;
        private String pid;
        private String name;
        private String code;
    }

    /**
     * 级联查询省市列表
     *
     * @param model
     * @return
     */
    public DataBean getCityList(Model_getCityList model) {
        if (model.getParentId() == null || model.getParentId().equals("root")) {
            model.setParentId("1230769196661510146");
        }
        java.util.List<_CityModel_> list = dslContext.select(
                        SYS_CATEGORY.ID.as("id"),
                        SYS_CATEGORY.PID.as("pid"),
                        SYS_CATEGORY.NAME.as("name"),
                        SYS_CATEGORY.CODE.as("code")
                ).from(
                        SYS_CATEGORY
                )
                .where(
                        SYS_CATEGORY.PID.eq(model.getParentId())
                ).orderBy(
                        SYS_CATEGORY.ID.desc()
                ).fetchInto(_CityModel_.class);
        if (list == null || list.isEmpty()) {
            return DataBean.sucEmpty();
        }
        return suc(list, list.size(), "suc", "操作成功");
    }

    /**
     * 查询所有城市列表
     *
     * @return
     */
    public DataBean getAllCityList() {
        String parentId = "1230769196661510146";
        java.util.List<String> priIds = dslContext.select(
                        SYS_CATEGORY.ID.as("id"),
                        SYS_CATEGORY.PID.as("pid"),
                        SYS_CATEGORY.NAME.as("name"),
                        SYS_CATEGORY.CODE.as("code")
                ).from(
                        SYS_CATEGORY
                )
                .where(
                        SYS_CATEGORY.PID.eq(parentId)
                ).orderBy(
                        SYS_CATEGORY.ID.desc()
                ).fetchInto(String.class);

        java.util.List<_CityModel_> list = dslContext.select(
                        SYS_CATEGORY.ID.as("id"),
                        SYS_CATEGORY.PID.as("pid"),
                        SYS_CATEGORY.NAME.as("name"),
                        SYS_CATEGORY.CODE.as("code")
                ).from(
                        SYS_CATEGORY
                )
                .where(
                        SYS_CATEGORY.PID.in(priIds)
                ).orderBy(
                        SYS_CATEGORY.ID.desc()
                ).fetchInto(_CityModel_.class);
        if (list == null || list.isEmpty()) {
            return DataBean.sucEmpty();
        }
        return suc(list, list.size(), "suc", "操作成功");
    }

    @Data
    @Builder
    @AllArgsConstructor
    @NoArgsConstructor
    @EqualsAndHashCode
    public static class Model_getCityScenicList {
        private String cityId;
    }

    @Data
    @Builder
    @AllArgsConstructor
    @NoArgsConstructor
    @EqualsAndHashCode
    public static class _ScenicModel_ {
        private String id;
        private String scenicTitle;
    }

    /**
     * 查询城市景点
     *
     * @param model
     * @return
     */
    public DataBean getCityScenicList(Model_getCityScenicList model) {
        java.util.List<_ScenicModel_> list = dslContext.select(
                        BS_SCENIC.ID.as("id"),
                        BS_SCENIC.TITLE.as("scenicTitle")
                ).from(
                        BS_SCENIC
                ).where(
                        BS_SCENIC.TRASH.eq(false)
                )
                .and(BS_SCENIC.CITYID.eq(model.getCityId()))
                .orderBy(BS_SCENIC.ID.desc())
                .fetchInto(_ScenicModel_.class);
        if (list == null || list.isEmpty()) {
            return DataBean.sucEmpty();
        }

        return suc(list, list.size(), "suc", "操作成功");
    }

    @Data
    @Builder
    @AllArgsConstructor
    @NoArgsConstructor
    @EqualsAndHashCode
    public static class Model_getPreTravelListByCity {
        private String cityId;
        private Integer dayNum;
    }

    /**
     * 查询目的地城市中的预设路线
     *
     * @param model
     * @return
     */
    public DataBean getPreTravelListByCity(
            Model_getPreTravelListByCity model
    ) {
        try {
            return dslContext.transactionResult(ctx -> {
                java.util.List<BsTravelLinePlatPreTravelLineDTO> preTravelLineList = new ArrayList<>();
                preTravelLineList.addAll(dslContext.selectFrom(
                                BS_TRAVELLINE_PLATPRETRAVELLINE
                        ).where(
                                BS_TRAVELLINE_PLATPRETRAVELLINE.TRASH.eq(false)
                        ).and(
                                BS_TRAVELLINE_PLATPRETRAVELLINE.OPENED.eq(true)
                        ).and(
                                BS_TRAVELLINE_PLATPRETRAVELLINE.ID.in(
                                        DSL.select(
                                                BS_TRAVELLINE_PRETRAVELLINESCENICGROUP.TRAVELLINEID
                                        ).from(
                                                BS_TRAVELLINE_PRETRAVELLINESCENICGROUP
                                        ).where(
                                                BS_TRAVELLINE_PRETRAVELLINESCENICGROUP.TRASH.eq(false)
                                        ).and(
                                                BS_TRAVELLINE_PRETRAVELLINESCENICGROUP.SCENICID.in(
                                                        DSL.select(
                                                                        BS_SCENIC.ID.as("id")
                                                                ).from(
                                                                        BS_SCENIC
                                                                ).where(
                                                                        BS_SCENIC.TRASH.eq(false)
                                                                )
                                                                .and(BS_SCENIC.CITYID.eq(model.getCityId()))

                                                )
                                        )
                                )
                        ).fetchInto(BsTravelLinePlatPreTravelLineDTO.class)
                );
                if (model.getDayNum() != null)
                    preTravelLineList = preTravelLineList.stream()
                            .filter(o -> {
                                return o.getMaxDay().equals(model.getDayNum());
                            }).collect(Collectors.toList());
                dslContext.commit();
                return suc(preTravelLineList, preTravelLineList.size(), "suc", "操作成功");
            });
        } catch (Exception e) {
            e.printStackTrace();
            return err("trans-err", e.getMessage());
        }
    }

    @Data
    @Builder
    @AllArgsConstructor
    @NoArgsConstructor
    @EqualsAndHashCode
    public static class Model_getPreTravelListBySenic {
        private String[] scenicIds;
        private Integer dayNum;
    }

    /**
     * 查询目的景点相关的预设路线
     *
     * @param model
     * @return
     */
    public DataBean getPreTravelListBySenic(
            Model_getPreTravelListBySenic model
    ) {
        try {
            return dslContext.transactionResult(ctx -> {
                java.util.List<BsTravelLinePlatPreTravelLineDTO> preTravelLineList = new ArrayList<>();
                preTravelLineList.addAll(dslContext.selectFrom(
                                BS_TRAVELLINE_PLATPRETRAVELLINE
                        ).where(
                                BS_TRAVELLINE_PLATPRETRAVELLINE.TRASH.eq(false)
                        ).and(
                                BS_TRAVELLINE_PLATPRETRAVELLINE.OPENED.eq(true)
                        ).and(
                                BS_TRAVELLINE_PLATPRETRAVELLINE.ID.in(
                                        DSL.select(
                                                BS_TRAVELLINE_PRETRAVELLINESCENICGROUP.TRAVELLINEID
                                        ).from(
                                                BS_TRAVELLINE_PRETRAVELLINESCENICGROUP
                                        ).where(
                                                BS_TRAVELLINE_PRETRAVELLINESCENICGROUP.TRASH.eq(false)
                                        ).and(
                                                BS_TRAVELLINE_PRETRAVELLINESCENICGROUP.SCENICID.in(
                                                        DSL.select(
                                                                        BS_SCENIC.ID.as("id")
                                                                ).from(
                                                                        BS_SCENIC
                                                                ).where(
                                                                        BS_SCENIC.TRASH.eq(false)
                                                                )
                                                                .and(BS_SCENIC.ID.in(model.getScenicIds()))

                                                )
                                        )
                                )
                        ).fetchInto(BsTravelLinePlatPreTravelLineDTO.class)
                );
                if (model.getDayNum() != null)
                    preTravelLineList = preTravelLineList.stream()
                            .filter(o -> {
                                return o.getMaxDay().equals(model.getDayNum());
                            }).collect(Collectors.toList());
                dslContext.commit();
                return suc(preTravelLineList, preTravelLineList.size(), "suc", "操作成功");
            });
        } catch (Exception e) {
            e.printStackTrace();
            return err("trans-err", e.getMessage());
        }
    }


    @Data
    @Builder
    @AllArgsConstructor
    @NoArgsConstructor
    @EqualsAndHashCode
    public static class Model_getCityScenicListByKey {
        private String key;
        private Integer cpage;
        private Integer pagesize;
    }

    /**
     * 根据关键词检索出景点
     *
     * @param model
     * @return
     */
    public DataBean getCityScenicListByKey(Model_getCityScenicListByKey model) {
        int count = dslContext.selectCount().from(
                        BS_SCENIC
                ).where(
                        BS_SCENIC.TRASH.eq(false)
                )
                .and(
                        model.getKey() == null || model.getKey().equals("")
                                ? DSL.noCondition() :
                                BS_SCENIC.TITLE.like(model.getKey() + "%")
                ).fetchOne().value1();
        java.util.List<_ScenicModel_> list = dslContext.select(
                        BS_SCENIC.ID.as("id"),
                        BS_SCENIC.TITLE.as("scenicTitle")
                ).from(
                        BS_SCENIC
                ).where(
                        BS_SCENIC.TRASH.eq(false)
                )
                .and(
                        model.getKey() == null || model.getKey().equals("")
                                ? DSL.noCondition() :
                                BS_SCENIC.TITLE.like(model.getKey() + "%")
                )
                .orderBy(BS_SCENIC.ID.desc())
                .limit(model.getCpage() * model.getPagesize(), model.getPagesize())
                .fetchInto(_ScenicModel_.class);
        if (list == null || list.isEmpty()) {
            return DataBean.sucEmpty();
        }
        return suc(list, count, "suc", "操作成功");
    }


    @Data
    @Builder
    @AllArgsConstructor
    @NoArgsConstructor
    @EqualsAndHashCode
    public static class Model_getTravelGroupList {
        private java.util.List<String> scenicId;//景点ID
        private String startDate;//发车时间
    }

    @Data
    @Builder
    @AllArgsConstructor
    @NoArgsConstructor
    @EqualsAndHashCode
    public static class _Count_Map_ {
        private Integer n;
        private String id;
    }

    /**
     * 小团查询出来的对象
     */
    @Data
    @Builder
    @AllArgsConstructor
    @NoArgsConstructor
    @EqualsAndHashCode
    public static class _TravelGroupVPO_ {
        private String id;
        private Integer travelDays;
        private String preTravelLineId;
        private String travelTitle;
        private Long startDate;
        private Integer maxUserNum;
        private String extInfor;
        private String images;
        private Integer peopleNum;
        private String startFromCity;
        private String startFromCityId;
    }

    /**
     * 查询旅游团-大小团
     *
     * @param model
     * @return
     */
    public DataBean getTravelGroupList(
            Model_getTravelGroupList model
    ) {
        java.util.List<String> travelGroupList = new ArrayList<>();//小团ID
        java.util.List<String> travelListGroupList = new ArrayList<>();//大团ID
        CountDownLatch latch = new CountDownLatch(3);
        //查询小团ID
        executor.execute(() -> {
            try {
                java.util.List<String> ids = dslContext.select(
                                BS_TRAVELGROUP_MAINTUORTRAVELLINERECORD.ID
                        ).from(BS_TRAVELGROUP_MAINTUORTRAVELLINERECORD)
                        .where(
                                BS_TRAVELGROUP_MAINTUORTRAVELLINERECORD.TYPE.eq(Enum_TourTravelGroupType.Self.getCode())
                        )
                        .and(BS_TRAVELGROUP_MAINTUORTRAVELLINERECORD.STATS.eq(
                                Enum_MainTourTravelLineStats.Wait.getCode()
                        ))
                        .and(BS_TRAVELGROUP_MAINTUORTRAVELLINERECORD.STARTDATE.eq(DateUtil.parse(model.getStartDate()).getTime()))
                        .and(BS_TRAVELGROUP_MAINTUORTRAVELLINERECORD.PRETRAVELLINEID.in(
                                DSL.select(BS_TRAVELLINE_PLATPRETRAVELLINE.ID)
                                        .from(BS_TRAVELLINE_PLATPRETRAVELLINE)
                                        .where(
                                                BS_TRAVELLINE_PLATPRETRAVELLINE.TRASH.eq(false)
                                        )
                                        .and(BS_TRAVELLINE_PLATPRETRAVELLINE.OPENED.eq(true))
                                        .and(BS_TRAVELLINE_PLATPRETRAVELLINE.ID.in(
                                                DSL.select(BS_TRAVELLINE_PRETRAVELLINESCENICGROUP.TRAVELLINEID)
                                                        .from(BS_TRAVELLINE_PRETRAVELLINESCENICGROUP)
                                                        .where(
                                                                BS_TRAVELLINE_PRETRAVELLINESCENICGROUP.TRASH.eq(false)
                                                        )
                                                        .and(BS_TRAVELLINE_PRETRAVELLINESCENICGROUP.SCENICID.in(model.getScenicId()))
                                        ))
                        ))
                        .orderBy(
                                BS_TRAVELGROUP_MAINTUORTRAVELLINERECORD.ID.desc()
                        )
                        .fetchInto(String.class);
                travelGroupList.addAll(ids);
                log.info("【小团IDs】->{}", ids);
            } finally {
                latch.countDown();
            }
        });
        //查询大团ID
        executor.execute(() -> {
            try {
                java.util.List<String> ids = dslContext.selectDistinct(
                                BS_TRAVELGROUP_MAINTOURTRAVELRECORDBINDTRAVELLISTGROUP.TRAVELLISTGROUPID
                        )
                        .from(BS_TRAVELGROUP_MAINTOURTRAVELRECORDBINDTRAVELLISTGROUP)
                        .where(
                                BS_TRAVELGROUP_MAINTOURTRAVELRECORDBINDTRAVELLISTGROUP.MAINTOURTRAVELRECORDID.in(
                                        DSL.select(
                                                        BS_TRAVELGROUP_MAINTUORTRAVELLINERECORD.ID
                                                ).from(BS_TRAVELGROUP_MAINTUORTRAVELLINERECORD)
                                                .where(
                                                        BS_TRAVELGROUP_MAINTUORTRAVELLINERECORD.TYPE.eq(Enum_TourTravelGroupType.Group.getCode())
                                                )
                                                .and(BS_TRAVELGROUP_MAINTUORTRAVELLINERECORD.STATS.eq(
                                                        Enum_MainTourTravelLineStats.Wait.getCode()
                                                ))
                                                .and(
                                                        model.getStartDate() != null ?
                                                                BS_TRAVELGROUP_MAINTUORTRAVELLINERECORD.STARTDATE.eq(DateUtil.parse(model.getStartDate()).getTime())
                                                                : DSL.noCondition()
                                                )
                                                .and(BS_TRAVELGROUP_MAINTUORTRAVELLINERECORD.PRETRAVELLINEID.in(
                                                        DSL.select(Tables.BS_TRAVELLINE_PLATPRETRAVELLINE.ID)
                                                                .from(Tables.BS_TRAVELLINE_PLATPRETRAVELLINE)
                                                                .where(
                                                                        Tables.BS_TRAVELLINE_PLATPRETRAVELLINE.TRASH.eq(false)
                                                                )
                                                                .and(Tables.BS_TRAVELLINE_PLATPRETRAVELLINE.OPENED.eq(true))
                                                                .and(
                                                                        model.getScenicId() != null ?
                                                                                Tables.BS_TRAVELLINE_PLATPRETRAVELLINE.ID.in(
                                                                                        DSL.select(BS_TRAVELLINE_PRETRAVELLINESCENICGROUP.TRAVELLINEID)
                                                                                                .from(BS_TRAVELLINE_PRETRAVELLINESCENICGROUP)
                                                                                                .where(
                                                                                                        BS_TRAVELLINE_PRETRAVELLINESCENICGROUP.TRASH.eq(false)
                                                                                                )
                                                                                                .and(BS_TRAVELLINE_PRETRAVELLINESCENICGROUP.SCENICID.in(model.getScenicId()))
                                                                                )
                                                                                : DSL.noCondition()
                                                                )
                                                ))
                                )
                        )
                        .orderBy(BS_TRAVELGROUP_MAINTOURTRAVELRECORDBINDTRAVELLISTGROUP.TRAVELLISTGROUPID.desc())
                        .fetchInto(String.class);
                travelListGroupList.addAll(ids);
            } finally {
                latch.countDown();
            }
        });
        //查询预设团
        java.util.List<BsTravelLinePlatPreTravelLineDTO> preTravelLineList = new ArrayList<>();
        executor.execute(() -> {
            try {
                preTravelLineList.addAll(dslContext.selectFrom(
                                BS_TRAVELLINE_PLATPRETRAVELLINE
                        ).where(
                                BS_TRAVELLINE_PLATPRETRAVELLINE.TRASH.eq(false)
                        ).and(
                                BS_TRAVELLINE_PLATPRETRAVELLINE.OPENED.eq(true)
                        ).and(
                                BS_TRAVELLINE_PLATPRETRAVELLINE.ID.in(
                                        DSL.select(
                                                BS_TRAVELLINE_PRETRAVELLINESCENICGROUP.TRAVELLINEID
                                        ).from(
                                                BS_TRAVELLINE_PRETRAVELLINESCENICGROUP
                                        ).where(
                                                BS_TRAVELLINE_PRETRAVELLINESCENICGROUP.TRASH.eq(false)
                                        ).and(
                                                BS_TRAVELLINE_PRETRAVELLINESCENICGROUP.SCENICID.in(model.getScenicId())
                                        )
                                )
                        ).fetchInto(BsTravelLinePlatPreTravelLineDTO.class)
                );
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                latch.countDown();
            }
        });

        //等待两个线程结束
        try {
            latch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        CountDownLatch latch2 = new CountDownLatch(2);
        java.util.Map<String, Integer> groupNumMap = new HashMap<>();//小团报名人数
        java.util.Map<String, Integer> groupListNumMap = new HashMap<>();//大团报名人数

        java.util.List<BSTravelPageWrapper_TravelGroupVPO> rslist1 = new ArrayList<>();// 小团列表
        java.util.List<BSTravelPageWrapper_TravelGroupVPO> rslist2 = new ArrayList<>();// 大团列表

        //查询小团报名人数，以及内容
        executor.execute(() -> {
            try {
                //统计人数
                java.util.List<_Count_Map_> idNums = dslContext.select(
                                DSL.ifnull(DSL.count(BS_TRAVELGROUP_TOURORDERRECORD.ID), 0).as("n"),
                                BS_TRAVELGROUP_TOURORDERRECORD.TRAVELGROUPID.as("id")
                        )
                        .from(
                                BS_TRAVELGROUP_TOURORDERRECORD
                        ).where(
                                BS_TRAVELGROUP_TOURORDERRECORD.STATS.in(
                                        Enum_TravelGroupTourOrderStats.Join.getCode(),
                                        Enum_TravelGroupTourOrderStats.Mark.getCode(),
                                        Enum_TravelGroupTourOrderStats.Waitpay.getCode(),
                                        Enum_TravelGroupTourOrderStats.Payed.getCode()
                                )
                        ).and(
                                BS_TRAVELGROUP_TOURORDERRECORD.TRAVELGROUPID.in(travelGroupList)
                        ).groupBy(
                                BS_TRAVELGROUP_TOURORDERRECORD.TRAVELGROUPID
                        ).fetchInto(_Count_Map_.class);
                if (idNums == null || idNums.isEmpty()) {
                    idNums = new ArrayList<>();
//                    return;
                }
                idNums.forEach(o -> {
                    groupNumMap.put(o.getId(), o.getN());
                });
                //查询内容
                java.util.List<_TravelGroupVPO_> list = dslContext.select(
                                BS_TRAVELGROUP_MAINTUORTRAVELLINERECORD.ID,
                                BS_TRAVELGROUP_MAINTUORTRAVELLINERECORD.TRAVELDAYS,
                                BS_TRAVELGROUP_MAINTUORTRAVELLINERECORD.PRETRAVELLINEID,
                                BS_TRAVELGROUP_MAINTUORTRAVELLINERECORD.TRAVELTITLE,
                                BS_TRAVELGROUP_MAINTUORTRAVELLINERECORD.STARTDATE,
                                BS_TRAVELGROUP_MAINTUORTRAVELLINERECORD.MAXUSERNUM,
                                BS_TRAVELGROUP_MAINTUORTRAVELLINERECORD.EXTINFOR,
                                BS_TRAVELLINE_PLATPRETRAVELLINE.IMAGES,
                                DSL.field(" 0  ").as("peopleNum"),
                                BS_TRAVELGROUP_STARTFROMCITY.CITYNAME.as("startFromCity"),
                                BS_TRAVELGROUP_STARTFROMCITY.CITYID.as("startFromCityId")
                        ).from(
                                BS_TRAVELGROUP_MAINTUORTRAVELLINERECORD
                        ).leftJoin(
                                BS_TRAVELLINE_PLATPRETRAVELLINE
                        ).on(BS_TRAVELLINE_PLATPRETRAVELLINE.ID.eq(BS_TRAVELGROUP_MAINTUORTRAVELLINERECORD.PRETRAVELLINEID))
                        .leftJoin(BS_TRAVELGROUP_STARTFROMCITY)
                        .on(BS_TRAVELGROUP_STARTFROMCITY.TRAVELGROUPID.eq(BS_TRAVELGROUP_MAINTUORTRAVELLINERECORD.ID))
                        .where(
                                BS_TRAVELGROUP_MAINTUORTRAVELLINERECORD.ID.in(travelGroupList)
                        ).fetchInto(_TravelGroupVPO_.class);
                Gson gson = new Gson();
                list.forEach(o -> {
                    BSTravelPageWrapper_TravelGroupVPO vpo = new BSTravelPageWrapper_TravelGroupVPO();
                    vpo.setId(o.getId());
                    vpo.setTravelDays(o.getTravelDays());
                    vpo.setPreTravelLineId(o.getPreTravelLineId());
                    vpo.setTravelTitle(o.getTravelTitle());
                    vpo.setStartDate(o.getStartDate());
                    vpo.setMaxUserNum(o.getMaxUserNum());
                    vpo.setExtInfor(gson.fromJson(o.getExtInfor(), java.util.Map.class));
                    try {
                        vpo.setImages(gson.fromJson(o.getImages(), java.util.List.class));
                    } catch (Exception e) {
                        e.printStackTrace();
                        vpo.setImages(vpo.getImages());
                    }
                    vpo.setPeopleNum(groupNumMap.get(o.getId()));
                    rslist1.add(vpo);
                });
                log.info("【小团报名】->{}", rslist1);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                latch2.countDown();
            }
        });
        //查询大团报名人数，以及内容
        executor.execute(() -> {
            try {
                //查询大团人数
//            java.util.List<TravelPageWrapper._Count_Map_> idNums = dslContext.select(
//                           DSL.ifnull( DSL.count(BS_TRAVELGROUP_TOURORDERRECORD.ID),0).as("n"),
//                            BS_TRAVELGROUP_TOURORDERRECORD.TRAVELGROUPID.as("id")
//                    )
//                    .from(
//                            BS_TRAVELGROUP_TOURORDERRECORD
//                    ).where(
//                            BS_TRAVELGROUP_TOURORDERRECORD.STATS.in(
//                                    Enum_TravelGroupTourOrderStats.Join.getCode(),
//                                    Enum_TravelGroupTourOrderStats.Mark.getCode(),
//                                    Enum_TravelGroupTourOrderStats.Waitpay.getCode(),
//                                    Enum_TravelGroupTourOrderStats.Payed.getCode()
//                            )
//                    ).and(
//                            BS_TRAVELGROUP_TOURORDERRECORD.TRAVELGROUPID.in(
//                                    DSL.select(
//                                                    BS_TRAVELGROUP_MAINTOURTRAVELRECORDBINDTRAVELLISTGROUP.MAINTOURTRAVELRECORDID
//                                            ).from(
//                                                    BS_TRAVELGROUP_MAINTOURTRAVELRECORDBINDTRAVELLISTGROUP,
//                                                    BS_TRAVELGROUP_TRAVELISTGROUP
//                                            ).where(
//                                                    BS_TRAVELGROUP_TRAVELISTGROUP.ID.in(travelListGroupList)
//                                            )
//                                            .and(
//                                                    BS_TRAVELGROUP_TRAVELISTGROUP.ID.eq(
//                                                            BS_TRAVELGROUP_MAINTOURTRAVELRECORDBINDTRAVELLISTGROUP.TRAVELLISTGROUPID
//                                                    )
//                                            )
//                            )
//                    ).groupBy(
//                            BS_TRAVELGROUP_TOURORDERRECORD.TRAVELGROUPID
//                    ).fetchInto(TravelPageWrapper._Count_Map_.class);

                java.util.List<TravelPageWrapper._Count_Map_> idNums = dslContext.select(
                                DSL.count(DSL.field("rid")).as("n"),
                                DSL.field("t.id")
                        )
                        .from(
                                DSL.selectDistinct(
                                                BS_TRAVELGROUP_MAINTOURTRAVELRECORDBINDTRAVELLISTGROUP.TRAVELLISTGROUPID.as("id"),
                                                BS_TRAVELGROUP_TOURORDERRECORD.ID.as("rid")
                                        ).from(
                                                BS_TRAVELGROUP_MAINTOURTRAVELRECORDBINDTRAVELLISTGROUP,
                                                BS_TRAVELGROUP_TOURORDERRECORD
                                        )
                                        .where(
                                                BS_TRAVELGROUP_MAINTOURTRAVELRECORDBINDTRAVELLISTGROUP.TRAVELLISTGROUPID.in(travelListGroupList)
                                        )
                                        .and(
                                                BS_TRAVELGROUP_TOURORDERRECORD.STATS.in(
                                                        Enum_TravelGroupTourOrderStats.Join.getCode(),
                                                        Enum_TravelGroupTourOrderStats.Mark.getCode(),
                                                        Enum_TravelGroupTourOrderStats.Waitpay.getCode(),
                                                        Enum_TravelGroupTourOrderStats.Payed.getCode()
                                                )
                                        )
                                        .and(
                                                BS_TRAVELGROUP_MAINTOURTRAVELRECORDBINDTRAVELLISTGROUP.MAINTOURTRAVELRECORDID.eq(
                                                        BS_TRAVELGROUP_TOURORDERRECORD.TRAVELGROUPID
                                                )
                                        ).asTable("t")
                        )
                        .groupBy(DSL.field("t.id"))
                        .fetchInto(TravelPageWrapper._Count_Map_.class);
                if (idNums == null || idNums.isEmpty()) {
                    idNums = new java.util.ArrayList<>();
//                    return;
                }
                idNums.forEach(o -> {
                    groupListNumMap.put(o.getId(), o.getN());
                });

                //查询大团信息
                java.util.List<TravelPageWrapper._TravelGroupVPO_> list = dslContext.selectDistinct(
                                BS_TRAVELGROUP_TRAVELISTGROUP.ID,
                                BS_TRAVELGROUP_MAINTUORTRAVELLINERECORD.TRAVELDAYS,
                                BS_TRAVELGROUP_MAINTUORTRAVELLINERECORD.PRETRAVELLINEID,
                                BS_TRAVELGROUP_MAINTUORTRAVELLINERECORD.TRAVELTITLE,
                                BS_TRAVELGROUP_TRAVELISTGROUP.STARTDATE,
                                BS_TRAVELGROUP_MAINTUORTRAVELLINERECORD.MAXUSERNUM,
                                BS_TRAVELGROUP_TRAVELISTGROUP.EXTINFOR,
                                Tables.BS_TRAVELLINE_PLATPRETRAVELLINE.IMAGES,
                                DSL.field(" 0 ").as("peopleNum"),
                                BS_TRAVELGROUP_STARTFROMCITY.CITYNAME.as("startFromCity"),
                                BS_TRAVELGROUP_STARTFROMCITY.CITYID.as("startFromCityId")
                        ).from(
                                DSL.select(
                                                BS_TRAVELGROUP_MAINTOURTRAVELRECORDBINDTRAVELLISTGROUP.MAINTOURTRAVELRECORDID,
                                                BS_TRAVELGROUP_MAINTOURTRAVELRECORDBINDTRAVELLISTGROUP.TRAVELLISTGROUPID.as("travelListGroupID")
                                        ).from(BS_TRAVELGROUP_MAINTOURTRAVELRECORDBINDTRAVELLISTGROUP)
                                        .where(
                                                BS_TRAVELGROUP_MAINTOURTRAVELRECORDBINDTRAVELLISTGROUP.TRAVELLISTGROUPID.in(travelListGroupList)
                                        ).asTable("t")
                        ).leftJoin(BS_TRAVELGROUP_MAINTUORTRAVELLINERECORD)
                        .on(BS_TRAVELGROUP_MAINTUORTRAVELLINERECORD.ID.eq(DSL.field("t.mainTourTravelRecordId", String.class)))
                        .leftJoin(
                                Tables.BS_TRAVELLINE_PLATPRETRAVELLINE
                        ).on(Tables.BS_TRAVELLINE_PLATPRETRAVELLINE.ID.eq(BS_TRAVELGROUP_MAINTUORTRAVELLINERECORD.PRETRAVELLINEID))
                        .leftJoin(BS_TRAVELGROUP_TRAVELISTGROUP)
                        .on(BS_TRAVELGROUP_TRAVELISTGROUP.ID.eq(DSL.field("t.travelListGroupID", String.class)))
                        .leftJoin(BS_TRAVELGROUP_STARTFROMCITY)
                        .on(BS_TRAVELGROUP_STARTFROMCITY.TRAVELGROUPID.eq(BS_TRAVELGROUP_MAINTUORTRAVELLINERECORD.ID))
                        .orderBy(BS_TRAVELGROUP_TRAVELISTGROUP.STARTDATE.desc())
                        .fetchInto(TravelPageWrapper._TravelGroupVPO_.class);

                Gson gson = new Gson();
                list.forEach(o -> {
                    BSTravelPageWrapper_TravelGroupVPO vpo = new BSTravelPageWrapper_TravelGroupVPO();
                    vpo.setId(o.getId());
                    vpo.setTravelDays(o.getTravelDays());
                    vpo.setPreTravelLineId(o.getPreTravelLineId());
                    vpo.setTravelTitle(o.getTravelTitle());
                    vpo.setStartDate(o.getStartDate());
                    vpo.setMaxUserNum(o.getMaxUserNum());
                    vpo.setExtInfor(gson.fromJson(o.getExtInfor(), java.util.Map.class));
                    try {
                        vpo.setImages(gson.fromJson(o.getImages(), java.util.List.class));
                    } catch (Exception e) {
                        vpo.setImages(Arrays.asList(o.getImages().split(",")));
                    }
                    vpo.setPeopleNum(groupListNumMap.get(o.getId()));
                    rslist2.add(vpo);
                });
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                latch2.countDown();
            }
        });

        try {
            latch2.await();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        //返回
        java.util.Map<String, java.util.List> rsMap = Map.of(
                "Self", rslist1,
                "Group", rslist2,
                "Propose", preTravelLineList
        );
        return suc(rsMap, rsMap.size(), "suc", "操作成功");
    }


    /**
     * 首页获取推荐团列表
     *
     * @return
     */
    public DataBean getHomePageTravelGroupListByKey(TravelLineImpl.Model_getHomePageTravelGroupListByKey model) {
        return travelLineImpl.getHomePageTravelGroupListByKey(model);
    }


    /**
     * 查询出旅游路线详情
     *
     * @return
     */
    public DataBean getPreTravelLineDetail(TravelLineImpl.Model_getTravelLineDetail model) {
        return travelLineImpl.getPreTravelLineDetail(model);
    }

    /**
     * 查询小团详情
     *
     * @param model
     * @return
     */
    public DataBean getMainTravelLineRecordById(TourTravelImpl.Model_getMainTravelLineRecordById model) {
        return tourTravelImpl.getMainTravelLineRecordById(model);
    }

    /**
     * 查询大团详情
     *
     * @param model
     * @return
     */
    public DataBean getTravelListGroupById(TravelLineImpl.Model_getTravelListGroupById model) {
        return travelLineImpl.getTravelListGroupById(model);
    }


    @Autowired
    private CommentImpl commentImpl;


    /**
     * 创建评论
     *
     * @param model
     * @return
     */
    public DataBean createComment(CommentImpl.Model_createComment model) {
        return commentImpl.createComment(model);
    }


    /**
     * 查询评论--评论类型
     *
     * @param model
     * @return
     */
    public DataBean getCommentListByType(CommentImpl.Model_getCommentListByType model) {
        return commentImpl.getCommentListByType(model);
    }

    /**
     * 点赞
     *
     * @param model
     * @return
     */
    public DataBean doZan(CommentImpl.Model_doZan model) {
        return commentImpl.doZan(model);
    }

    /**
     * 查询活动类型
     *
     * @return
     */
    public DataBean getActiveTypeList() {
        String r = redisUtil.get("TravelActiveType");
        if (r == null) {
            return DataBean.errEmpty();
        }
//        Gson gson = new Gson();
        return suc(new JSONArray(r), 1, "suc", "操作成功");
    }

    /**
     * 查询拼搭子类型
     *
     * @return
     */
    public DataBean getTravelGroupTypeList() {
        String r = redisUtil.get("TravelGroupType");
        if (r == null) {
            return DataBean.errEmpty();
        }
//        Gson gson = new Gson();
        return suc(new JSONArray(r), 1, "suc", "操作成功");
    }

    /**
     * 获取用户券
     *
     * @param model
     * @return
     */
    public DataBean getUserTicketListBy(
            UserTicketImpl.Model_getUserTicketListBy model
    ) {
        return userTicketImpl.getUserTicketListBy(model);
    }


    @Data
    @Builder
    @AllArgsConstructor
    @NoArgsConstructor
    @EqualsAndHashCode
    public static class Model_getTravelPickUpByCity {
        private String cityId;
    }

    @Data
    @Builder
    @AllArgsConstructor
    @NoArgsConstructor
    @EqualsAndHashCode
    public static class VPO_getTravelPickUpByCity {
        private String id;
        private String gis;
        private String address;
    }

    /**
     * 获取上车点
     *
     * @param model
     * @return
     */
    public DataBean getTravelPickUpByCity(
            Model_getTravelPickUpByCity model
    ) {
        try {
            return dslContext.transactionResult(ctx -> {
                //todo
                java.util.List<VPO_getTravelPickUpByCity> list = null;
                try {
                    list = dslContext.resultQuery(
                            "SELECT\n" +
                                    "couple_pick_up_point.id,\n" +
                                    "couple_pick_up_point.lot_and_lat as gis,\n" +
                                    "couple_pick_up_point.address\n" +
                                    "\n" +
                                    "FROM\n" +
                                    "couple_pick_up_point\n" +
                                    "WHERE\n" +
                                    "couple_pick_up_point.city_id =?",
                            model.getCityId()
                    ).fetchInto(VPO_getTravelPickUpByCity.class);
                } catch (Exception e) {
                    e.printStackTrace();
                    return DataBean.sucEmpty();
                }
                if (list == null || list.isEmpty()) {
                    return DataBean.sucEmpty();
                }

                dslContext.commit();
                return suc(list, list.size(), "suc", "操作成功");
            });
        } catch (Exception e) {
            e.printStackTrace();
            return err("trans-err", e.getMessage());
        }
    }
}
